﻿<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
  
  <head>
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-39155502-5"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
  
      gtag('config', 'UA-39155502-5');
    </script>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>GridFS alternative | MongoDB.Entities </title>
    <meta name="viewport" content="width=device-width">
    <meta name="title" content="GridFS alternative | MongoDB.Entities ">
    <meta name="generator" content="docfx 2.58.0.0">
    <meta name="description" content="A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management.">
    <link rel="shortcut icon" href="../images/favicon.ico">
    <link rel="stylesheet" href="../styles/docfx.vendor.css">
    <link rel="stylesheet" href="../styles/docfx.css">
    <link rel="stylesheet" href="../styles/main.css">
    <meta property="docfx:navrel" content="../toc.html">
    <meta property="docfx:tocrel" content="toc.html">
    
    <meta property="docfx:rel" content="../">
    <meta property="docfx:newtab" content="true">
    <meta property="og:title" content="MongoDB.Entities">
    <meta property="og:site_name" content="MongoDB.Entities">
    <meta property="og:url" content="https://mongodb-entities.com">
    <meta property="og:description" content="A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management,">
    <meta property="og:type" content="website">
    <meta property="og:image" content="https://mongodb-entities.com/images/social-square.png">  
  </head>
  <body data-spy="scroll" data-target="#affix" data-offset="120">
    <div id="wrapper">
      <header>
        
        <nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
          <div class="container">
            <div class="navbar-header">
              <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              
              <a class="navbar-brand" href="../index.html">
                <img id="logo" class="svg" src="../images/icon.png" alt="">
              </a>
            </div>
            <div class="collapse navbar-collapse" id="navbar">
              <form class="navbar-form navbar-right" role="search" id="search">
                <div class="form-group">
                  <input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
                </div>
              </form>
            </div>
          </div>
        </nav>
        
        <div class="subnav navbar navbar-default">
          <div class="container hide-when-search" id="breadcrumb">
            <ul class="breadcrumb">
              <li></li>
            </ul>
          </div>
        </div>
      </header>
      <div class="container body-content">
        
        <div id="search-results">
          <div class="search-list">Search Results for <span></span></div>
          <div class="sr-items">
            <p><i class="glyphicon glyphicon-refresh index-loading"></i></p>
          </div>
          <ul id="pagination" data-first="First" data-prev="Previous" data-next="Next" data-last="Last"></ul>
        </div>
      </div>
      <div role="main" class="container body-content hide-when-search">
        
        <div class="sidenav hide-when-search">
          <a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
          <div class="sidetoggle collapse" id="sidetoggle">
            <div id="sidetoc"></div>
          </div>
        </div>
        <div class="article row grid-right">
          <div class="col-md-10">
            <article class="content wrap" id="_content" data-uid="">
<h1 id="gridfs-alternative">GridFS alternative</h1>

<p>this library features a GridFS alternative where you can stream upload &amp; download files in chunks to keep memory usage at a minimum when dealing with large files. there is no limitation on the size or type of file you can store and the API is designed to be much simpler than GridFS.</p>
<h3 id="define-a-file-entity">Define a file entity</h3>
<p>inherit from <code>FileEntity</code> abstract class instead of the usual <code>Entity</code> class for defining your file entities like below. You can add any other properties you wish to store with it.</p>
<pre><code class="lang-csharp">public class Picture : FileEntity
{
    public string Title { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}
</code></pre>
<p>the <code>FileEntity</code> is a sub class of <code>Entity</code> class. so all operations supported by the library can be performed with these file entities.</p>
<h3 id="upload-data">Upload data</h3>
<p>before uploading data for a file entity, you must save the file entity first. then simply call the upload method like below by supplying a stream object for it to read the data from:</p>
<pre><code class="lang-csharp">var kitty = new Picture
{
    Title = &quot;NiceKitty.jpg&quot;,
    Width = 4000,
    Height = 4000
};

await kitty.SaveAsync();

var streamTask = new HttpClient()
                      .GetStreamAsync(&quot;https://placekitten.com/g/4000/4000&quot;);

using (var stream = await streamTask)
{
    await kitty.Data.UploadAsync(stream);
}
</code></pre>
<p>the <code>Data</code> property on the file entity gives you access to a couple of methods for uploading and downloading. with those methods, you can specify <em>upload chunk size</em>, <em>download batch size</em>, <em>operation timeout period</em>, as well as <em>cancellation token</em> for controlling the process.</p>
<p>in addition to the properties you added, there will also be <code>FileSize</code>, <code>ChunkCount</code> &amp; <code>UploadSuccessful</code> properties on the file entity. the file size reports how much data has been read from the stream in bytes if the upload is still in progress or the total file size if the upload is complete. chunk count reports how many number of pieces the file has been broken into for storage. <em>UploadSuccessful</em> will only return true if the process completed without any issues.</p>
<h3 id="download-data">Download data</h3>
<pre><code class="lang-csharp">var picture = await DB.Find&lt;Picture&gt;()
                      .Match(p =&gt; p.Title == &quot;NiceKitty.jpg&quot;)
                      .ExecuteSingleAsync();

using (var stream = File.OpenWrite(&quot;kitty.jpg&quot;))
{
    await picture.Data.DownloadAsync(stream);
}
</code></pre>
<p>first retrieve the file entity you want to work with and then call the <code>.Data.DownloadAsync()</code> method by supplying it a stream object to write the data to.</p>
<p>alternatively, if the ID of the file entity is known, you can avoid fetching the file entity from the database and access the data directly like so:</p>
<pre><code class="lang-csharp">await DB.File&lt;Picture&gt;(&quot;xxxxxxxxx&quot;).DownloadAsync(stream);
</code></pre>
<h3 id="transaction-support">Transaction support</h3>
<p>uploading &amp; downloading file data within a transaction requires passing in a session to the upload and download methods. see <a href="Transactions.html#file-storage">here</a> for an example.</p>
</article>
          </div>
          
          <div class="hidden-sm col-md-2" role="complementary">
            <div class="sideaffix">
              <div class="contribution">
                <ul class="nav">
                </ul>
              </div>
              <nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
                <h5>In This Article</h5>
                <div></div>
              </nav>
            </div>
          </div>
        </div>
      </div>
      
      <footer>
        <div class="grad-bottom"></div>
        <div class="footer">
          <div class="container">
            <span class="pull-right">
              <a href="#top">Back to top</a>
            </span>
            Developed by <a href='https://github.com/dj-nitehawk'>Đĵ ΝιΓΞΗΛψΚ</a> and <a href='https://github.com/dj-nitehawk/MongoDB.Entities/graphs/contributors'>contributors</a> / Licensed under <a href='https://github.com/dj-nitehawk/MongoDB.Entities/blob/master/LICENSE'>MIT</a> / Website generated by <a href='https://dotnet.github.io/docfx/'>DocFX</a>
            
          </div>
        </div>
      </footer>
    </div>
    
    <script type="text/javascript" src="../styles/docfx.vendor.js"></script>
    <script type="text/javascript" src="../styles/docfx.js"></script>
    <script type="text/javascript" src="../styles/main.js"></script>
  </body>
</html>
